package com.zbystudy.factory;

import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.apache.commons.lang3.StringUtils.*;

/**
 * Created By zby on 21:42 2019/4/1
 */
public class PackageEntityFactory implements EntityFactory {

    private static Set<File> entitySets = new HashSet<>();

    private static PackageEntityFactory instance = null;

    private PackageEntityFactory() {

    }

    /**
     * Created By zby on 23:14 2019/4/1
     * 实例化工厂对象
     */
    public static PackageEntityFactory getInstance() {
        if (null == instance) {
            instance = new PackageEntityFactory();
        }
        return instance;
    }

    //    包的路径
    private static String PACKAGE_PATH = null;

    @Override
    public Set<File> loadEntityFiles(String poPackage, boolean fromConfigFile) {
        setEntitySets(poPackage, null, fromConfigFile);
        return entitySets;
    }

    @Override
    public List<String> loadEntityFileNames(String poPackage, boolean fromConfigFile) {
        Set<File> entitySets = loadEntityFiles(poPackage, fromConfigFile);
        List<String> entityFileNames = new ArrayList<>();
        if (entitySets.isEmpty()) {
            return null;
        }
        for (File file : entitySets) {
            String path = file.getAbsolutePath();
            path = substring(path, path.indexOf("classes") + 8, path.lastIndexOf("."));
            path = replace(path, "\\", ".");
            entityFileNames.add(path);
        }
        return entityFileNames;
    }

    @Override
    public String parsePackagePath(String poPackage, boolean fromConfigFile) {
        String packageName = getPackage(poPackage, fromConfigFile);
        if (contains(packageName, "*")) {
            packageName = substring(packageName, 0, packageName.lastIndexOf("."));
            PACKAGE_PATH = packageName;
        }
        String targetClasses = this.getClass().getResource("").getPath();
        packageName = StringUtils.substring(targetClasses, 0, targetClasses.indexOf("classes"))
                + "classes/" + packageName.replace(".", "/");
        return substring(packageName, 1, packageName.length());
    }

    @Override
    public String getPackage(String poPackage, boolean fromConfigFile) {
        if (isBlank(PACKAGE_PATH)) {
            initPackagePath(poPackage, fromConfigFile);
        }
        return PACKAGE_PATH;
    }

    @Override
    public String packageChildPath(String poPackage, boolean fromConfigFile, String filePath) {
        String packageName = parsePackagePath(poPackage, fromConfigFile);
        String childPath = null;
        if (isNotBlank(filePath)) {
            filePath = replace(filePath, "\\", "/");
        }
        if (filePath.contains(packageName)) {
            childPath = substring(filePath, packageName.length(), filePath.length());
        }
        return childPath;
    }

    /**
     * Created By zby on 15:28 2019/4/1
     * 初始化po包的路径
     *
     * @param poPackage      包名
     * @param fromConfigFile 是否来源于配置文件
     */
    private static void initPackagePath(String poPackage, boolean fromConfigFile) {
        if (isBlank(poPackage)) {
            throw new RuntimeException("请填写po类的文件夹的包路径");
        }
        String packagePath = fromConfigFile ? sqlConnectFactory.getProperties().getProperty(poPackage) : poPackage;
        if (isBlank(packagePath)) {
            throw new RuntimeException("包名不能为空");
        }
        if (isBlank(PACKAGE_PATH)) {
            PACKAGE_PATH = packagePath;
        }
    }

    /**
     * Created By zby on 14:41 2019/4/1
     *
     * @param poPackage      包名，如果不传，默认是jdbc.package名字
     * @param childDirectory vo父类下子类包名
     * @param fromConfigFile 是否来源于配置文件
     */
    private void setEntitySets(String poPackage, String childDirectory, boolean fromConfigFile) {
        String packageName = parsePackagePath(poPackage, fromConfigFile);
        packageName = isBlank(childDirectory) ? packageName : (packageName + childDirectory);
        File packageFile = new File(packageName);
        if (packageFile.isDirectory()) {
            File[] entityFiles = packageFile.listFiles();
            if (entityFiles != null && entityFiles.length > 0) {
                for (File entityFile : entityFiles) {
                    if (entityFile.isDirectory()) {
                        String childPath = packageChildPath(poPackage, fromConfigFile, entityFile.getAbsolutePath());
                        setEntitySets(poPackage, childPath, fromConfigFile);
                        continue;
                    }
                    entitySets.add(entityFile);
                }
            }
        }
    }
}
